package org.japo.java.entities;

import java.io.Serializable;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.StringTokenizer;

/**
 *
 * @author José A. Pacheco Ondoño - joanpaon@gmail.com
 */
public class Hora implements Serializable {

    // Separador de hora
    public static final String SEPARADOR = ":";

    // Campos de la hora
    private int h;
    private int m;
    private int s;

    public Hora() {
        // Instancia un objeto GregorianCalendar
        GregorianCalendar gc = new GregorianCalendar();

        // Obtiene la hora del sistema
        h = gc.get(Calendar.HOUR_OF_DAY);
        m = gc.get(Calendar.MINUTE);
        s = gc.get(Calendar.SECOND);
    }

    public Hora(int h, int m, int s) {
        if (validarHora(h, m, s)) {
            this.h = h;
            this.m = m;
            this.s = s;
        } else {
            // Instancia un objeto GregorianCalendar
            GregorianCalendar gc = new GregorianCalendar();

            // Obtiene la hora del sistema
            this.h = gc.get(Calendar.HOUR_OF_DAY);
            this.m = gc.get(Calendar.MINUTE);
            this.s = gc.get(Calendar.SECOND);
        }
    }

    public int getH() {
        return h;
    }

    public void setH(int h) {
        if (validarHora(h, m, s)) {
            this.h = h;
        }
    }

    public int getM() {
        return m;
    }

    public void setM(int m) {
        if (validarHora(h, m, s)) {
            this.m = m;
        }
    }

    public int getS() {
        return s;
    }

    public void setS(int s) {
        if (validarHora(h, m, s)) {
            this.s = s;
        }
    }

    public static Hora parseHora(String textoHora) throws NumberFormatException {
        // Referencia al objeto a devolver
        Hora hora = new Hora();

        // Crea un objeto StringTokenizer a partir del dato
        StringTokenizer st = new StringTokenizer(textoHora.trim(), SEPARADOR);

        // Analiza el objeto creado
        if (st.countTokens() == 3) {
            // H
            int hAct = Integer.parseInt(st.nextToken().trim());

            // M
            int mAct = Integer.parseInt(st.nextToken().trim());

            // Año
            int sAct = Integer.parseInt(st.nextToken().trim());

            // Valida la hora
            if (validarHora(hAct, mAct, sAct)) {
                hora = new Hora(hAct, mAct, sAct);
            } else {
                throw new NumberFormatException();
            }
        } else {
            throw new NumberFormatException();
        }

        // Devuelve la hora generada
        return hora;
    }

    public static boolean validarHora(int hTest, int mTest, int sTest) {
        return hTest >= 0 && hTest <= 23 &&
               mTest >= 0 && mTest <= 59 &&
               sTest >= 0 && sTest <= 59;
    }

    public static boolean validarBisiesto(int stest) {
        return stest % 400 == 0 || stest % 100 != 0 && stest % 4 == 0;
    }

    public static Hora obtenerHoraSistema() {
        // Instancia un objeto GregorianCalendar
        GregorianCalendar gc = new GregorianCalendar();

        // Obtiene la hora del sistema
        int hAct = gc.get(Calendar.HOUR_OF_DAY);
        int mAct = gc.get(Calendar.MINUTE);
        int sAct = gc.get(Calendar.SECOND);

        // Instancia un hora con los valores obtenidos
        return new Hora(hAct, mAct, sAct);
    }

    public String obtenerHoraTexto() {
        return String.format("%02d" + SEPARADOR + "%02d" + SEPARADOR + "%02d",
                h, m, s);
    }

    @Override
    public String toString() {
        return obtenerHoraTexto();
    }

    
    @Override
    public boolean equals(Object o) {
        // Semáforo de señalización
        boolean horaOK = false;

        // Análisis del objeto pasado
        if (o instanceof Hora) {
            // Convierte el objeto actual a hora
            Hora hora = (Hora) o;

            // Compara los valores de la hora
            horaOK = h == hora.h && m == hora.m && s == hora.s;
        }

        // Devuelve el resultado del análisis
        return horaOK;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 67 * hash + this.h;
        hash = 67 * hash + this.m;
        hash = 67 * hash + this.s;
        return hash;
    }
}
